var util = require('util');
var ws = require('websocket-lib');
var master = require('./master');
var worker = require('./worker');

var ServerSession = ws.Server.Session;
var ClientSession = ws.Client.Session;

function ClusterServerSession() {
	ServerSession.apply(this, arguments);
	this.channels = [];
	this.on('data', function (json) {
		try {
			var msg = JSON.parse(json);
			var event = msg['event'];
			var channel = msg['channel'];
			var data = msg['data'];
			if (event === 'subscribe') {
				this.subscribe(channel);
			} else if (event === 'unsubscribe') {
				this.unsubscribe(channel);
			} else if (event === 'publish') {
				this.emit('message', channel, data);
			}
		} catch (e) {
		}
	});
	worker.attach(this);
}

util.inherits(ClusterServerSession, ServerSession);

ClusterServerSession.prototype.subscribe = function (channel) {
	if (channel) {
		var index = this.channels.indexOf(channel);
		if (index < 0) {
			this.channels.push(channel);
			this.emit('subscribe', channel);
		}
	}
};

ClusterServerSession.prototype.unsubscribe = function (channel) {
	if (channel) {
		var index = this.channels.indexOf(channel);
		if (index >= 0) {
			this.channels.splice(index, 1);
			this.emit('unsubscribe', channel);
		}
	}
};

ClusterServerSession.prototype.publish = function (channel, data, callback) {
	if (channel && data) {
		this.sendText(JSON.stringify({
			event: 'publish',
			channel: channel,
			data: data
		}), callback);
	}
};

ws.Server.Session = ClusterServerSession;

function ClusterClientSession() {
	ClientSession.apply(this, arguments);
	this.on('data', function (json) {
		try {
			var msg = JSON.parse(json);
			var event = msg['event'];
			var channel = msg['channel'];
			var data = msg['data'];
			if (event === 'publish') {
				this.emit('message', channel, data);
			}
		} catch (e) {
		}
	});
}

util.inherits(ClusterClientSession, ClientSession);

ClusterClientSession.prototype.subscribe = function (channel, callback) {
	if (channel) {
		this.sendText(JSON.stringify({
			event: 'subscribe',
			channel: channel
		}), callback);
	}
};

ClusterClientSession.prototype.unsubscribe = function (channel, callback) {
	if (channel) {
		this.sendText(JSON.stringify({
			event: 'unsubscribe',
			channel: channel
		}), callback);
	}
};

ClusterClientSession.prototype.publish = function (channel, data, callback) {
	if (channel && data) {
		this.sendText(JSON.stringify({
			event: 'publish',
			channel: channel,
			data: data
		}), callback);
	}
};

ws.Client.Session = ClusterClientSession;

exports.createServer = function (options, requestListener) {
	if (options && options['broker']) {
		worker.setBroker(options['broker']);
	} else {
		worker.setBroker(require('./broker'));
	}
	exports.createServer = function () {
		throw new Error('Multi server in one process is not supported now');
	};
	return new ws.Server(options, requestListener);
};

exports.createConnection = exports.connect = ws.connect;
